package com.yundows.safe.pick;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;

interface Interface {
	int getStatus();

	List<Map<String, Object>> getList();

	void onChange(Intent intent);

	void setHandler(Handler handler);
}

public class DataService extends Service {

	List<Object> queue = new ArrayList<Object>();
	int status = -1;

	PackageManager pm;

	List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

	Map<Character, Character> t9 = new HashMap<Character, Character>();
	{
		t9.put('a', '2');
		t9.put('b', '2');
		t9.put('c', '2');
		t9.put('d', '3');
		t9.put('e', '3');
		t9.put('f', '3');
		t9.put('g', '4');
		t9.put('h', '4');
		t9.put('i', '4');
		t9.put('j', '5');
		t9.put('k', '5');
		t9.put('l', '5');
		t9.put('m', '6');
		t9.put('n', '6');
		t9.put('o', '6');
		t9.put('p', '7');
		t9.put('q', '7');
		t9.put('r', '7');
		t9.put('s', '7');
		t9.put('t', '8');
		t9.put('u', '8');
		t9.put('v', '8');
		t9.put('w', '9');
		t9.put('x', '9');
		t9.put('y', '9');
		t9.put('z', '9');

		t9.put(' ', '0');
		t9.put('0', '0');

		t9.put('1', '1');
		t9.put('2', '2');
		t9.put('3', '3');
		t9.put('4', '4');
		t9.put('5', '5');
		t9.put('6', '6');
		t9.put('7', '7');
		t9.put('8', '8');
		t9.put('9', '9');
	}

	private boolean threadDisable;

	ServiceBinder serviceBinder = new ServiceBinder();

	Handler handler;

	private Handler packageHandler;

	private boolean loadingApp = false;

	public class ServiceBinder extends Binder implements Interface {
		@Override
		public int getStatus() {
			return status;
		}

		@Override
		public List<Map<String, Object>> getList() {
			return list;
		}

		@Override
		public void onChange(Intent intent) {
		}

		@Override
		public void setHandler(Handler handler) {
			DataService.this.handler = handler;
			update();
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return serviceBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		pm = getPackageManager();

		loadApps();

		monitorPackage();

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (!threadDisable) {
					try {
						Thread.sleep(1000 * 60);
					} catch (InterruptedException e) {
					}
					// count++;
					// Log.v(" CountService ", " Count is " + count);
				}
			}
		}).start();
	}

	private void monitorPackage() {
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_PACKAGE_ADDED);
		filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
		filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
		filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
		filter.addDataScheme("package");
		packageHandler = new Handler(new Callback() {
			@Override
			public boolean handleMessage(Message msg) {
				onPackageChanged((Intent) msg.obj);
				return false;
			}
		});
		registerReceiver(new BroadcastReceiver() {
			@Override
			public void onReceive(Context arg0, Intent arg1) {
				Message msg = new Message();
				msg.obj = arg1;
				packageHandler.sendMessage(msg);
			}
		}, filter);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		this.threadDisable = true;
		Log.v(" CountService ", " on destroy ");
	}

	public void loadApps() {
		if (status == -1) {
			list.clear();
			pm = getPackageManager();
			new Thread(new Runnable() {

				public void run() {
					status++;

					loadAppByIntent(new Intent(Intent.ACTION_MAIN, null), null);

					status++;
					update();
				}
			}).start();
		}
	}

	private void loadAppByIntent(Intent _intent, String _packageName) {
		if (_packageName != null) {
			queue.add(_packageName);
		}
		if (_intent != null) {
			queue.add(_intent);
		}
		if (!loadingApp) {
			loadingApp = true;
			for (int r = queue.size() - 1; r > -1; r--) {
				if (queue.get(r) instanceof String) {
					String packageName = (String) queue.remove(r);
					for (int i = list.size() - 1; i > -1; i--) {
						if (list.get(i).containsKey("resolveInfo")) {
							ResolveInfo resolveInfo = (ResolveInfo) list.get(i)
									.get("resolveInfo");
							if (resolveInfo.activityInfo.packageName
									.equals(packageName)) {
								list.remove(i);
							}
						}
					}
				}
			}

			for (int r = queue.size() - 1; r > -1; r--) {
				if (queue.get(r) instanceof Intent) {
					Intent intent = (Intent) queue.remove(r);
					List<ResolveInfo> packages = pm.queryIntentActivities(
							intent.addCategory(Intent.CATEGORY_LAUNCHER), 0);
					if (packages != null) {
						for (ResolveInfo resolveInfo : packages) {
							HashMap<String, Object> item = new HashMap<String, Object>();
							item.put("label", resolveInfo.loadLabel(pm));
							List<String> keywordsList = (List<String>) SpellChinese
									.getKeywords(item.get("label").toString());
							if (keywordsList.size() > 0) {
								item.put("keywords", keywordsList);
								item.put("indices", convert(keywordsList));
								item.put("resolveInfo", resolveInfo);
								list.add(item);
							}
						}
					}
				}
			}
			loadingApp = false;

			if (status == 1) {
				update();
			}
			if (queue.size() > 0) {
				loadAppByIntent(null, null);
			}
		}
	}

	private List<String> convert(List<String> keywordsList) {
		ArrayList<String> ret = new ArrayList<String>(keywordsList.size());
		for (int i = 0; i < keywordsList.size(); i++) {
			String keyword = keywordsList.get(i).toLowerCase();
			StringBuffer sb = new StringBuffer();
			for (int j = 0; j < keyword.length(); j++) {
				Character ch = t9.get(keyword.charAt(j));
				if (ch != null) {
					sb.append(ch);
				}
			}
			ret.add(sb.toString());
		}
		return ret;
	}

	private void update() {
		if (handler != null) {
			handler.sendEmptyMessage(0);
		}
	}

	private void onPackageChanged(Intent arg1) {

		String packageName = arg1.getDataString()
				.substring("package:".length());

		loadAppByIntent(
				new Intent(Intent.ACTION_MAIN, null).setPackage(packageName),
				packageName);

	}
}
